/*
Copyright © 2021 NAME HERE <EMAIL ADDRESS>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd

import (
	"fmt"
	"gitee.com/maomaomaoge/go-utils/file"
	"gitee.com/maomaomaoge/go-utils/version"
	"io/fs"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/spf13/cobra"
)

// createCmd represents the create command
var createCmd = &cobra.Command{
	Use:   "cdoc",
	Short: "文档成成short",
	Long: `文档成成long`,
	Run: func(cmd *cobra.Command, args []string) {
		createInit()
		//CreateDoc()
		CreateMd()
		fmt.Println("文档生成ok")
	},

}

func init() {
	rootCmd.AddCommand(createCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// createCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// createCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

const (
	_defaultFunc = `// func:`
	_defaultAim = `// aim:`

	// md文
	mdFile = "./doc/doc.md"
)

var allData *Tree
var projectGoPathDir string
var HtmlFile string

func createInit()  {
	fmt.Println("create init")
	g, err := getGoPath()
	if err != nil {
		fmt.Println("获取go path 失败")
		panic(err)
	}
	projectGoPathDir = filepath.Clean(g + `\pkg\mod\gitee.com\maomaomaoge`)

	//fmt.Println("html")
	//HtmlFile, err = getHtmlDocDir()
	//if err != nil {
	//	log.Fatalln("??", err)
	//}
}

type Tree struct {
	Data []string
}

func NewTree() *Tree {
	t := &Tree{}
	t.Data = make([]string, 0)
	return t
}

func getGoPath() (string, error) {
	var res string
	output, err := exec.Command("go", "env").Output()
	if err != nil {
		return "", err
	}
	for _, v := range strings.Split(strings.ReplaceAll(string(output), "set", ""), "\n") {
		if strings.Contains(v, "GOPATH=") {
			res = strings.TrimSpace(strings.ReplaceAll(v, "GOPATH=", ""))
		}
	}

	return res, nil
}

func getDoc() (string, error) {
	var res string
	gp, err := getGoPath()
	if err != nil {
		log.Fatalln(err)
	}

	recursion, err := file.GetDirListNoRecursion(filepath.Clean(gp + `\pkg\mod\gitee.com\maomaomaoge`))
	if err != nil {
		return res, err
	}

	noParser := make([]string, 0)
	for _, v := range recursion {
		noParser = append(noParser, strings.ReplaceAll(v, "go-utils_linux@", ""))
	}

	version, err := version.GetLastVersion_Three(noParser)
	if err != nil {
		log.Fatalln(err)
		return res, err
	}
	fmt.Println("文档版本: ", version)

	d := ""
	for _, v := range recursion {
		if strings.Contains(v, version) {
			d = v
		}
	}

	res = filepath.Clean(gp + `\pkg\mod\gitee.com\maomaomaoge\` + d + `\doc\doc.txt`)

	return res, nil
}

func getHtmlDocDir() (string, error) {
	var res string
	gp, err := getGoPath()
	if err != nil {
		log.Fatalln(err)
	}

	recursion, err := file.GetDirListNoRecursion(filepath.Clean(gp + `\pkg\mod\gitee.com\maomaomaoge`))
	if err != nil {
		return res, err
	}

	noParser := make([]string, 0)
	for _, v := range recursion {
		noParser = append(noParser, strings.ReplaceAll(v, "go-utils_linux@", ""))
	}

	version, err := version.GetLastVersion_Three(noParser)
	if err != nil {
		log.Fatalln("版本解析失败:", err)
		return res, err
	}
	fmt.Println("文档版本: ", version)

	d := ""
	for _, v := range recursion {
		if strings.Contains(v, version) {
			d = v
		}
	}

	res = filepath.Clean(gp + `\pkg\mod\gitee.com\maomaomaoge\` + d + `\doc`)

	res = strings.ReplaceAll(res, `\`, `/`)

	return res, nil
}


// 读取文档
func ReadDoc()  {
	doc, err := getDoc()
	if err != nil {
		log.Fatalln(err)
		return
	}

	fmt.Println(doc)
	readFile, err := ioutil.ReadFile(doc)
	if err != nil {
		log.Fatalln(err)
	}

	fmt.Println(string(readFile))
}

// 创建文档
func CreateDoc()  {
	err2 := os.RemoveAll("./doc/doc.txt")
	if err2 != nil {
		log.Fatalln(err2)
		return
	}
	allData = NewTree()
	filepath.Walk("./", func(path string, info fs.FileInfo, err error) error {
		if info.IsDir() {
			return nil
		}

		data, err := ioutil.ReadFile(path)
		if err != nil {
			return err
		}
		// 逐行读取数据，找到特殊定义
		split := strings.Split(string(data), "\n")
		for _, v := range split {
			if strings.Contains(v, _defaultAim) {
				allData.Data = append(allData.Data,path +  v + "\n\n")
			} else if strings.Contains(v, _defaultFunc) {
				allData.Data = append(allData.Data,path +  v)
			}
		}

		return nil
	})

	str := ""
	for _, v := range allData.Data {
		str += strings.ReplaceAll(v, `//`, "") + "\n"
	}

	create, err := os.Create("./doc/doc.txt")
	if err != nil {
		return
	}
	defer create.Close()

	ioutil.WriteFile("./doc/doc.txt", []byte(str), os.ModeAppend)
}

// 创建md
func CreateMd()  {
	fmt.Println("create md")
	err2 := os.RemoveAll(mdFile)
	if err2 != nil {
		log.Fatalln(err2)
		return
	}
	allData = NewTree()
	filepath.Walk("./", func(path string, info fs.FileInfo, err error) error {
		if info.IsDir() {
			have, err := file.HaveFileInDir(path)
			if err != nil {
				return err
			}
			if !have {
				return nil
			}
			if filterMd(path) {
				return nil
			}

			// 加上目录的4级标题
			allData.Data = append(allData.Data,"\n\n")
			allData.Data = append(allData.Data,"#### " + path  + "\n")

			return nil
		}

		data, err := ioutil.ReadFile(path)
		if err != nil {
			return err
		}
		// 逐行读取数据，找到特殊定义
		split := strings.Split(string(data), "\n")
		for _, v := range split {
			if strings.Contains(v, _defaultAim) {
				allData.Data = append(allData.Data,path +  v + "\n")
				allData.Data = append(allData.Data, "```" + "\n\n\n")
			} else if strings.Contains(v, _defaultFunc) {
				// md文件的第一个
				allData.Data = append(allData.Data, "```" + "\n")
				allData.Data = append(allData.Data,path +  v)
			}
		}

		return nil
	})

	str := ""
	for _, v := range allData.Data {
		str += strings.ReplaceAll(v, `//`, "") + "\n"
	}

	create, err := os.Create(mdFile)
	if err != nil {
		return
	}
	defer create.Close()

	ioutil.WriteFile(mdFile, []byte(str), os.ModeAppend)
}

// 过滤不需要的文件
func filterMd(s string) bool {
	if strings.Contains(s, "git") {
		return true
	}
	if strings.Contains(s, "test") {
		return true
	}
	if strings.Contains(s, ".idea") {
		return true
	}
	if s == "./" {
		return true
	}
	if s == "doc" {
		return true
	}

	return false
}
